from Gui import *
import ctypes
import threading
import math
##usb = ctypes.cdll.LoadLibrary('usb.dll')
##usb.initialize()
##buffer = ctypes.c_buffer(8)
##def set_ra1_callback():
##    usb.control_transfer(dev, 0x40, SET_RA1, 0, 0, 0, buffer)
##
##def clr_ra1_callback():
##    usb.control_transfer(dev, 0x40, CLR_RA1, 0, 0, 0, buffer)

# def get_ra2_callback():
#     usb.control_transfer(dev, 0xC0, GET_RA2, 0, 0, 1, buffer)
#     status.configure(text = 'RA2 is currently %d.' % ord(buffer[0]))

##def set_duty_callback(value):
##    usb.control_transfer(dev, 0x40, SET_DUTY, int(value), 0, 0, buffer)
##    
##def set_callback(pin):
##    global player
##    if not (pin in opponentpin or pin in playerpin):
##        usb.control_transfer(dev, 0x40, pin, 0, 0, 0, buffer)
##        img=PhotoImage(file=['X','O'][int(player)]+'.gif')
##        buttons[pin].configure(image=img)
##        buttons[pin].image=img
##        if player:
##            opponentpin.append(pin)
##        else:
##            playerpin.append(pin)
##        player = not player
##    
##def make_callback(pin):
##    return lambda: set_callback(pin)
##def update_status():
##    for pos in opponentpin:
##        usb.control_transfer(dev, 0xC0, pos, 0, 0, 1, buffer)
##    status.configure(text = 'It is %s''s turn.' % ['X', 'O'][int(player)])
##    root.after(50, update_status)
##
####def clear_board():
####        usb.control_transfer(dev, 0x40, 9, 0, 0, 0, buffer)
##
##root = Tk()
##root.title('Lab 3 GUI')
####fm = Frame(root)
####b=Button(root, width=20,text="First").grid(row=0)
####b=Button(root, width=20,text="Second").grid(row=1)
####b=Button(root, width=18,text="PAUL BOOTH").grid(row=0, column=1)
####b=Button(root, width=19,text="Blair's hair").grid(row=7, column=8)
##buttons=[]
##img=PhotoImage(file='blank.GIF')
##for i in xrange(9):
##    
####    print img
##    b=Button(root,  width=64,height=64, text=' ', image=img,command = make_callback(i))
##    b.image=img
##    b.grid(row=i/3, column=i%3)
##    buttons.append(b)
##    #b.pack(side = LEFT, padx=2, pady=2)
##    
##
###Button(fm, text = ' ', command = clr_ra1_callback).pack(side = LEFT)
### Button(fm, text = 'GET_RA2', command = get_ra2_callback).pack(side = LEFT)
###fm.pack(side = TOP)
###dutyslider = Scale(root, from_ = 0, to = 255, orient = HORIZONTAL, showvalue = FALSE, command = set_duty_callback)
###dutyslider.set(128)
###dutyslider.pack(side = TOP)
##status = Label(root, text = 'Get Ready for FUN.')
##status.grid(row=3,column=0,columnspan=3)
##b=Button(root, text = 'clear board', command = clear_board);
##b.grid(row=4,column=0,columnspan=3)
###status.pack(side = TOP)
##
##dev = usb.open_device(0x6666, 0x0003, 0)
##if dev<0:
##    print "No matching device found...\n"
##else:
##    ret = usb.control_transfer(dev, 0x00, 0x09, 1, 0, 0, buffer)
##    if ret<0:
##        print "Unable to send SET_CONFIGURATION standard request.\n"
##    clear_board()
##    root.after(30, update_status)
##    root.mainloop()
##    usb.close_device(dev)
class TowerGUI(Gui):
    def __init__(self):
        Gui.__init__(self)
        self.title('Noah Tye stole my project!!!!')
        self.ca_width = 1000
        self.ca_height = 800
        self.fr(LEFT, expand = 1)
        self.canvas = self.ca(width=self.ca_width, height=self.ca_height, bg='white')
        self.canvas.configure(width=self.ca_width, height=self.ca_height)
        self.canvas.bind("<Button-1>", self.clicked)
        self.canvas.pack()
        self.endfr()
        self.clicked_pos = None
        self.board=Board()
        #self.x=self.y=self.x2=self.y2=100
        self.redraw()
        thread1=threading.Thread(target=self.mainloop)
        thread1.start()
        self.infiniteloop()
        
    def redraw(self, event=None):
        #self.clear(False)
        #self.canvas.create_line(self.x,self.y,self.x2,self.y2, width=4, fill="blue")
        self.canvas.delete("all")
        self.board.draw(self.canvas)
        print self.board.theta
        
    def clicked(self, event):
        self.clicked_pos = (event.x, event.y)
        print self.clicked_pos
        self.redraw()
        
    def infiniteloop(self):
        while 1:
            self.board.update()
            self.redraw()
            
class CreepPath:
    
    def __init__(self):
        self.setup_path()
        
    def get_first_position(self, time):
        pass

    def setup_path(self):
        #each gear is x,y,r, direction
        #x,y position
        #r is radius of the gear
        self.gears=[(1,2,1/2.), (3,4,2./2), (-6,8,0.5]
        
    def delimeters(self):
        
        self.delimiters=[]
        cumdist = 0
        for i in range(len(self.gears)):
            ngear = self.gears[i-1] 
            n2gear = self.gears[i]
            (t1, t2) = cctangent(ngear, n2gear)

            th1 = math.atan2( (t2[0] - ngear[0]) , (t2[1] - ngear[1]) )
            th2 = math.atan2( (t1[0] - ngear[0]) , (t1[1] - ngear[1]) )
            if i > 1:
                arc = ngear[2]*(th1 - th2)
                tfirst = t2
                cumdist += abs(arc)
                self.delimiters.append((cumdist, t1[0], t1[1], th1, ngear[2], ngear[3]))
                       #total distance, x, y, initial angle, radius
            
            length = math.sqrt((t2[1] - t1[1])**2 + (t2[0] - t1[0])**2)
            cumdist += abs(length)
            self.delimiters.append((cumdist, t2[0], t2[1], 0, 0, 0))
                       #total distance, x, y               

        for delim in self.delimiters:
            print delim[0], '(', delim[1], ',', delim[2], ')'
        return self.delimiters

    def cctangent(self, c1, c2):u
        th_ini = math.atan2(c2.y-c1.y,c2.x-c1.x)
        l = math.sqrt((c2.y-c1.y)**2 + (c2x-c1.x)**2)
        th = math.acos((c1.r-c2.r)/l)
        t1x = c1x + r1 * math.cos(th+th_ini)
        t1y = c1y + r1 * math.sin(th+th_ini) 
        t2x = c2x + r2 * math.cos(th+th_ini)
        t2y = c2y + r2 * math.sin(th+th_ini)
        return (t1x, t1y, t2x, t2y)





    def get_xy_pos(self, d, dlist):
    #        d = self.rate*time - dist_behind
        for i in range(len(dlist)-1):
            #delimeters in the form [(d1, x1, y1, th_ini, r, bool), (d2, x2, y2)]
            #bool = 1: theta increasing; -1: theta decreasing
            p1 = dlist[i]
            p2 = dlist[i+1]
    #        print p1[0], p2[0], 'i =', i, p2[0] - p1[0]
            if d >= dlist[-1][0]:      #The front creep has done a lap
                return x, y
            if dlist[i][0] <= d < dlist[i+1][0]:
                print p1[0]
                #if i % 2 == 1:      #Even sections are linear
                x = p1[1] + d / (p2[0] - p1[0]) * (p2[1] - p1[1])
                y = p1[2] + d / (p2[0] - p1[0]) * (p2[2] - p1[2])
    ##            else:               #Odd sections are turns
    ##                x = p1[1] + math.cos(p1[3] + p1[5]*(d - p1[0])/p1[4])
    ##                y = p1[1] + math.sin(p1[3] + p1[5]*(d - p1[0])/p1[4])
                return x, y

    class Gear:

        def __init__(self, x,y,r, start_theta=0, end_theta=0):
            self.x = x
            self.y = y
            self.r = r
            self.start_theta=start_theta
            self.end_theta=end_theta
    
class Board:
    def __init__(self):
        self.creeps=[Creep(i) for i in xrange(10)]
        self.creepPath=CreepPath()
        self.towers=[]
        self.theta=0
        
    def update(self):
        for tower in self.towers:
            tower.update()
        self.theta=(self.theta+.001)%(2*math.pi)
        
            
    def draw(self, canvas):
        self.oval=canvas.create_oval(500-25, 500-25,
                               525, 525,
                               fill="black", activefill="red")
        self.line=canvas.create_line(500,500, 500+100*math.cos(self.theta),500+100*math.sin(self.theta), width=4, fill="blue")
                           
class Creep:
    def __init__(self, num=0, HP=10):
        self.num=num
        self.HP = HP
        self.x=0
        self.y=0

    def hurt(HPloss):
        self.HP-=HPloss
        return self.HP>0
    
towergui=TowerGUI()        
        